/*
 * Copyright (C), 2013-2017, 工人网
 * FileName: ParamSignUtils.java
 * Author:   yjg
 * Date:     2017年8月2日 下午1:31:33
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.gongren.oddjob.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能描述: 参数签名工具 Author: yjg@gongren.com Date: 2017年8月2日 下午1:31:33
 */
public class ParamSignUtils {

	public static final String SIGN = "sign";
	public static final String PARAM = "param";

	public static HashMap<String, String> sign(Map<String, String> paramValues, String secret) {
		return sign(paramValues, null, secret);
	}

	/**
	 * 
	 * 功能描述: 
	 * 
	 * @param paramValues 请求的参数
	 * @param ignoreParamNames 需要排除参数
	 * @param secretKey  密钥
	 * @return 
	 * Author:   yjg@gongren.com
	 * Date:     2017年8月2日 下午2:26:37
	 * Version: 1.0.0
	 */
	public static HashMap<String, String> sign(Map<String, String> paramValues, List<String> ignoreParamNames,
			String secretKey) {
		try {
			HashMap<String, String> signMap = new HashMap<String, String>();
			StringBuilder sb = new StringBuilder();
			List<String> paramNames = new ArrayList<String>(paramValues.size());
			paramNames.addAll(paramValues.keySet());
			if (ignoreParamNames != null && ignoreParamNames.size() > 0) {
				for (String ignoreParamName : ignoreParamNames) {
					paramNames.remove(ignoreParamName);
				}
			}
			Collections.sort(paramNames);
			sb.append(secretKey);
			for (String paramName : paramNames) {
				sb.append(paramName).append("=").append(paramValues.get(paramName));
			}
			sb.append(secretKey);
			byte[] md5Digest = getMD5Digest(sb.toString());
			String sign = byte2hex(md5Digest);
			signMap.put(SIGN, sign);
			return signMap;
		} catch (IOException e) {
			throw new RuntimeException("加密签名计算错误", e);
		}

	}

	public static String utf8Encoding(String value, String sourceCharsetName) {
		try {
			return new String(value.getBytes(sourceCharsetName), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new IllegalArgumentException(e);
		}
	}

	private static byte[] getMD5Digest(String data) throws IOException {
		byte[] bytes = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			bytes = md.digest(data.getBytes("UTF-8"));
		} catch (GeneralSecurityException gse) {
			throw new IOException(gse);
		}
		return bytes;
	}

	private static String byte2hex(byte[] bytes) {
		StringBuilder sign = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() == 1) {
				sign.append("0");
			}
			sign.append(hex.toUpperCase());
		}
		return sign.toString();
	}
}
